using System;
using System.Threading.Tasks;
using UnityEngine;
using UnityEngine.UI;
using TMPro;
using GamePlay.Framework.Network;
using Com.Lin.Proto;

namespace GamePlay.Features
{
    public class WebSocketConnector : MonoBehaviour
    {
        [SerializeField] private string defaultWebSocketUrl = "ws://10.198.40.195:9010";
        [SerializeField] private bool autoConnectOnStart = false;

        [SerializeField] private TMP_InputField urlInputField;
        [SerializeField] private Button connectButton;
        [SerializeField] private Button disconnectButton;
        [SerializeField] private TextMeshProUGUI statusText;
        [SerializeField] private TextMeshProUGUI messageLogText;
        [SerializeField] private Button loginButton;
        [SerializeField] private TMP_InputField usernameInput;
        [SerializeField] private TMP_InputField passwordInput;
        [SerializeField] private TextMeshProUGUI errorMessageText;

        private WebSocketClientWX webSocketClient;
        private bool isConnected = false;

        private void Awake()
        {
            // 确保WebSocketMessageHandler已初始化
            var messageHandler = WebSocketMessageHandler.Instance;

            webSocketClient = WebSocketClientWX.Instance;

            if (urlInputField != null)
            {
                urlInputField.text = defaultWebSocketUrl;
            }

            if (connectButton != null)
            {
                connectButton.onClick.AddListener(ConnectToServer);
            }

            if (disconnectButton != null)
            {
                disconnectButton.onClick.AddListener(DisconnectFromServer);
                disconnectButton.interactable = false;
            }

            if (loginButton != null)
            {
                loginButton.onClick.AddListener(Login);
                loginButton.interactable = false;
            }

            if (errorMessageText != null)
            {
                errorMessageText.text = "";
            }

            UpdateStatusText("未连接");
        }

        private void OnEnable()
        {
            RegisterEventHandlers();
        }

        private void OnDisable()
        {
            UnregisterEventHandlers();
        }

        private void Start()
        {
            if (autoConnectOnStart)
            {
                ConnectToServer();
            }
        }

        private void OnDestroy()
        {
            UnregisterEventHandlers();

            if (isConnected)
            {
                _ = webSocketClient.DisconnectAsync();
            }
        }

        public void ConnectToServer()
        {
            string url = urlInputField != null ? urlInputField.text : defaultWebSocketUrl;

            UpdateStatusText("正在连接...");
            AddToLog($"尝试连接到: {url}");

            UpdateErrorMessage("");

            webSocketClient.ConnectAsync(url, OnConnectResult);

            if (connectButton != null)
            {
                connectButton.interactable = false;
            }
        }

        public void DisconnectFromServer()
        {
            UpdateStatusText("正在断开连接...");
            AddToLog("正在断开连接...");

            _ = webSocketClient.DisconnectAsync();
        }

        public async new void SendMessage(string message)
        {
            if (!webSocketClient.IsConnectedAndReady())
            {
                UpdateErrorMessage("无法发送消息：WebSocket连接未就绪");
                AddToLog("无法发送消息：未连接到服务器或连接状态异常");
                return;
            }

            bool sendSuccess = await webSocketClient.SendTextAsync(message);
            if (sendSuccess)
            {
                AddToLog($"已发送: {message}");
            }
            else
            {
                UpdateErrorMessage("发送消息失败");
                AddToLog("发送消息失败");
            }
        }

        private void RegisterEventHandlers()
        {
            if (webSocketClient != null)
            {
                webSocketClient.OnConnected += OnConnected;
                webSocketClient.OnDisconnected += OnDisconnected;
                webSocketClient.OnError += OnError;
                webSocketClient.OnTextMessageReceived += OnTextMessageReceived;
                webSocketClient.OnBinaryMessageReceived += OnBinaryMessageReceived;
                webSocketClient.OnConnectionStatusChanged += OnConnectionStatusChanged;
            }
        }

        private void UnregisterEventHandlers()
        {
            if (webSocketClient != null)
            {
                webSocketClient.OnConnected -= OnConnected;
                webSocketClient.OnDisconnected -= OnDisconnected;
                webSocketClient.OnError -= OnError;
                webSocketClient.OnTextMessageReceived -= OnTextMessageReceived;
                webSocketClient.OnBinaryMessageReceived -= OnBinaryMessageReceived;
                webSocketClient.OnConnectionStatusChanged -= OnConnectionStatusChanged;
            }
        }

        private void OnConnectionStatusChanged(WebSocketClientWX.ConnectionStatus status)
        {
            string statusMessage = GetStatusMessage(status);
            UpdateStatusText(statusMessage);
            AddToLog($"连接状态变更: {status} - {statusMessage}");

            if (status == WebSocketClientWX.ConnectionStatus.Error ||
                status == WebSocketClientWX.ConnectionStatus.ConnectionFailed ||
                status == WebSocketClientWX.ConnectionStatus.Timeout ||
                status == WebSocketClientWX.ConnectionStatus.ServerUnreachable)
            {
                UpdateErrorMessage(webSocketClient.LastErrorMessage);
            }
            else
            {
                UpdateErrorMessage("");
            }

            UpdateButtonStates(status);
        }

        private string GetStatusMessage(WebSocketClientWX.ConnectionStatus status)
        {
            switch (status)
            {
                case WebSocketClientWX.ConnectionStatus.Connected:
                    return "已连接";
                case WebSocketClientWX.ConnectionStatus.Connecting:
                    return "正在连接...";
                case WebSocketClientWX.ConnectionStatus.Disconnected:
                    return "已断开连接";
                case WebSocketClientWX.ConnectionStatus.ConnectionFailed:
                    return "连接失败";
                case WebSocketClientWX.ConnectionStatus.ServerUnreachable:
                    return "服务器不可达";
                case WebSocketClientWX.ConnectionStatus.Timeout:
                    return "连接超时";
                case WebSocketClientWX.ConnectionStatus.Error:
                    return "连接错误";
                default:
                    return "未知状态";
            }
        }

        private void UpdateButtonStates(WebSocketClientWX.ConnectionStatus status)
        {
            bool isReady = status == WebSocketClientWX.ConnectionStatus.Connected;

            if (connectButton != null)
            {
                connectButton.interactable = !isReady &&
                    status != WebSocketClientWX.ConnectionStatus.Connecting;
            }

            if (disconnectButton != null)
            {
                disconnectButton.interactable = isReady;
            }

            if (loginButton != null)
            {
                loginButton.interactable = isReady;
            }
        }

        private void OnConnected()
        {
            isConnected = true;

            AddToLog("WebSocket连接已建立");
        }

        private void OnDisconnected(int code, string reason)
        {
            isConnected = false;

            AddToLog($"WebSocket断开连接: 代码={code}, 原因={reason}");
        }

        private void OnError(string errorMessage)
        {
            AddToLog($"WebSocket错误: {errorMessage}");
        }

        private void OnTextMessageReceived(string message)
        {
            AddToLog($"收到: {message}");
        }

        private void OnBinaryMessageReceived(byte[] data)
        {
            AddToLog($"收到二进制数据: {data.Length} 字节");
        }

        private void OnConnectResult(bool success)
        {
            if (!success)
            {
                AddToLog("连接回调返回：连接失败");
            }
            else
            {
                AddToLog("连接回调返回：连接成功");
            }
        }

        private void UpdateStatusText(string status)
        {
            if (statusText != null)
            {
                statusText.text = $"状态: {status}";
            }
        }

        private void UpdateErrorMessage(string message)
        {
            if (errorMessageText != null)
            {
                errorMessageText.text = message;
                errorMessageText.gameObject.SetActive(!string.IsNullOrEmpty(message));
            }
        }

        private void AddToLog(string message)
        {
            Debug.Log($"[WebSocket] {message}");

            if (messageLogText != null)
            {
                if (messageLogText.text.Length > 5000)
                {
                    messageLogText.text = messageLogText.text.Substring(messageLogText.text.Length - 4000);
                }
                messageLogText.text += $"\n[{DateTime.Now:HH:mm:ss}] {message}";
            }
        }

        public async void Login()
        {
            if (!webSocketClient.IsConnectedAndReady())
            {
                UpdateErrorMessage("请先连接到服务器");
                AddToLog("无法登录：WebSocket连接未就绪");
                return;
            }

            string username = usernameInput != null ? usernameInput.text : "";
            string password = passwordInput != null ? passwordInput.text : "";

            if (string.IsNullOrEmpty(username) || string.IsNullOrEmpty(password))
            {
                UpdateErrorMessage("用户名和密码不能为空");
                AddToLog("用户名和密码不能为空");
                return;
            }

            try
            {
                // 创建ProtoBuf登录消息
                var loginMessage = new ReqLoginMessage
                {
                    LoginType = 1, // 默认登录类型，根据需要调整
                    Token = $"{username}:{password}" // 将用户名和密码组合为token
                    // 注意：根据协议文件，这里可以设置SessionId用于重连，但当前示例不需要
                };

                // 使用WebSocketMessageHandler发送ProtoBuf消息 (内部使用RequestMsg基础包)
                WebSocketMessageHandler.Instance.SendProtobufMessage(100101, loginMessage, true, success =>
                {
                    if (success)
                    {
                        AddToLog($"发送ProtoBuf登录请求(使用RequestMsg基础包): 用户名={username}");
                    }
                    else
                    {
                        UpdateErrorMessage("发送ProtoBuf登录请求失败");
                        AddToLog("发送ProtoBuf登录请求失败");
                    }
                });
            }
            catch (Exception ex)
            {
                UpdateErrorMessage($"创建登录请求失败: {ex.Message}");
                AddToLog($"创建登录请求失败: {ex.Message}");
            }
        }
    }
}